<template>
    <div class="app-container">
        <div id="pnt" style="width: 10px;height: 10px;position: fixed;right: 0;top:0;background-color: #1971c2;"></div>
        <div class="top-toolbar">
            <a-row type="flex" align="middle">
                <a-divider type="vertical"></a-divider>
                <div :class="['icon-wrap subscript', { 'active': activeI === 0 }]" @click.prevent="onSelectTool(0)"
                    title="区域选择">
                    <i class="iconfont gls-kuangxuan"></i>
                </div>
                <div :class="['icon-wrap subscript', { 'active': activeI === 1 }]" @click.prevent="onSelectTool(1)"
                    title="单击创建矩形">
                    <i class="iconfont gls-zhengfangxing"></i>
                </div>
                <div :class="['icon-wrap subscript', { 'active': activeI === 2 }]" @click.prevent="onSelectTool(2)"
                    title="单击创建圆">
                    <i class="iconfont gls-yaunxing"></i>
                </div>
                <div :class="['icon-wrap subscript', { 'active': activeI === 3 }]" title="连续点击创建折线">
                    <i class="iconfont gls-zhixian"></i>
                    <ul class="list-wrap hover-tab" style="width: 120px;">
                        <li @click.prevent.stop="onSelectTool(3)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-jiguangbi" style="margin-right: 4px;"></i> <span>折线</span>
                            </a-row>
                        </li>
                        <li @click.prevent.stop="onSelectTool(3, true)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-jiguangbi" style="margin-right: 4px;"></i> <span>不规则区域</span>
                            </a-row>
                        </li>
                    </ul>
                </div>
                <div :class="['icon-wrap subscript', { 'active': activeI === 4 }]" title="自由画笔">
                    <i class="iconfont gls-huabi"></i>
                    <ul class="list-wrap hover-tab" style="width: 100px;">
                        <li @click.prevent.stop="onSelectTool(4)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-huabi" style="margin-right: 4px;"></i> <span>自由画笔</span>
                            </a-row>
                        </li>
                        <li @click.prevent.stop="onSelectTool(4, true)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-jiguangbi" style="margin-right: 4px;"></i> <span>激光笔</span>
                            </a-row>
                        </li>
                        <li @click.prevent.stop="onSelectTool(12, true)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-quxianbi" style="margin-right: 4px;"></i> <span>曲线笔</span>
                            </a-row>
                        </li>
                        <li @click.prevent.stop="onSelectTool(8)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-jiguangbi" style="margin-right: 4px;"></i> <span>像素笔</span>
                            </a-row>
                        </li>
                    </ul>
                </div>
                <div :class="['icon-wrap subscript', { 'active': activeI === 5 }]" @click.prevent="onSelectTool(5)"
                    title="单击创建文本">
                    <i class="iconfont gls-wenzi"></i>
                </div>
                <div :class="['icon-wrap subscript', { 'active': activeI === 6 }]" @click.prevent="onSelectTool(6)"
                    title="单击创建图片, 可上传图片或者svg">
                    <i class="iconfont gls-tupian"></i>
                </div>
                <div :class="['icon-wrap subscript', { 'active': activeI === 7 }]" @click.prevent="onSelectTool(7)"
                    title="网格背景">
                    <i class="iconfont gls-wanggeguan"></i>
                </div>
                <div :class="['icon-wrap subscript', { 'active': gls?.cbAdsorption }]" @click.prevent="onSelectTool(8)"
                    title="网格吸附">
                    <i class="iconfont gls-zidongxifu"></i>
                </div>
                <a-divider type="vertical"></a-divider>
                <div :class="['icon-wrap', { 'active': activeI === 8 }]" title="更多工具">
                    <i class="iconfont gls-gengduogongju"></i>
                    <ul class="list-wrap hover-tab" style="width: 150px;">
                        <li @click.prevent.stop="onSelectTool(10)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-fit-size" style="margin-right: 4px;"></i> <span>内容适应宽高</span>
                            </a-row>
                        </li>
                        <li @click.prevent.stop="onSelectTool(14)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-xiaoditu" style="margin-right: 4px;"></i> <span>小地图</span>
                            </a-row>
                        </li>
                        <li @click.prevent.stop="onSelectTool(15)">
                            <a-row type="flex" align="middle">
                                <i class="iconfont gls-biaochi" style="margin-right: 4px;"></i> <span>标尺</span>
                            </a-row>
                        </li>
                    </ul>
                </div>
                <div :class="['icon-wrap']" @click.prevent="onSelectTool(13)" title="取消画笔" style="width: 60px"
                    v-if="callback">
                    取消画笔
                </div>
            </a-row>
        </div>
        <div class="props-tab">
            <div class="icon-wrap gengduo" @click.prevent="isShowSide = !isShowSide">
                <i class="iconfont gls-gengduo"></i>
            </div>
            <div class="props-page" v-if="isShowSide" style="margin-right: 15px">
                <ul class="list-wrap">
                    <li @click.prevent="onImportFile"><i class="iconfont gls-xiazai" /> 打开 </li>
                    <li @click.prevent="onSaveFile"><i class="iconfont gls-xiazai" /> 保存到...</li>
                    <li @click.prevent="onShowPreview()"><i class="iconfont gls-daochutupian" /> 导出图片...</li>
                    <li @click.prevent="isShowHelp = true"><i class="iconfont gls-bangzhu" /> 帮助</li>
                    <li @click.prevent="reset(true)"><i class="iconfont gls-shanchu" /> 重置画布</li>
                    <!-- <li @click.prevent="darkTheme"><i class="iconfont gls-shanchu" /> 深色模式</li> -->
                    <a-divider type="horizonal"></a-divider>
                    <li @click.prevent="linkTo('https://space.bilibili.com/436686692?spm_id_from=333.788.0.0')"><i
                            class="iconfont gls-bilibili" /> 关注up实时进展...</li>
                    <a-divider type="horizonal"></a-divider>
                    <li class="canvas-bg">
                        <div class="title">画布背景</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button size="small" style="background-color: #ffc9c9"
                                @click.prevent="() => { gls && (gls.background = '#ffc9c9') }"></a-button>
                            <a-button size="small" style="background-color: #b2f2bb"
                                @click.prevent="() => { gls && (gls.background = '#b2f2bb') }"></a-button>
                            <a-button size="small" style="background-color: #a5d8ff"
                                @click.prevent="() => { gls && (gls.background = '#a5d8ff') }"></a-button>
                            <a-button size="small" style="background-color: #ffec99"
                                @click.prevent="() => { gls && (gls.background = '#ffec99') }"></a-button>
                            <a-divider type="vertical"></a-divider>
                            <input type="color" class="color-picker" ref="color-picker"
                                @input="(e: any) => { gls && (gls.background = e.target.value) }" />
                        </a-row>
                    </li>
                </ul>
            </div>
            <div class="props-page props-setting" v-if="isShowSide">
                <ul class="list-wrap">
                    <li>
                        <div class="title">描边色</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button size="middle" style="background-color: #e03131"
                                @click.prevent="modifyStrokeStyle('#e03131')"></a-button>
                            <a-button size="middle" style="background-color: #2f9e44"
                                @click.prevent="modifyStrokeStyle('#2f9e44')"></a-button>
                            <a-button size="middle" style="background-color: #1971c2"
                                @click.prevent="modifyStrokeStyle('#1971c2')"></a-button>
                            <a-button size="middle" style="background-color: #f08c00"
                                @click.prevent="modifyStrokeStyle('#f08c00')"></a-button>
                            <a-divider type="vertical"></a-divider>
                            <input type="color" class="color-picker" ref="color-picker"
                                @input="(e: any) => { modifyStrokeStyle(e.target.value) }" />
                        </a-row>
                    </li>
                    <li>
                        <div class="title">背景色</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button size="middle" style="background-color: #ffc9c9"
                                @click.prevent="modifyFillStyle('#ffc9c9')"></a-button>
                            <a-button size="middle" style="background-color: #b2f2bb"
                                @click.prevent="modifyFillStyle('#b2f2bb')"></a-button>
                            <a-button size="middle" style="background-color: #a5d8ff"
                                @click.prevent="modifyFillStyle('#a5d8ff')"></a-button>
                            <a-button size="middle" style="background-color: #ffec99"
                                @click.prevent="modifyFillStyle('#ffec99')"></a-button>
                            <a-divider type="vertical"></a-divider>
                            <input type="color" class="color-picker" ref="color-picker"
                                @input="(e: any) => { modifyFillStyle(e.target.value) }" />
                        </a-row>
                    </li>
                    <li>
                        <div class="title">描边宽度</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button style="background-color: hsl(240 25% 96%)" @click.prevent="modifyLineWidth(.1)"
                                title="细">
                                <i class="iconfont gls-xi-zhixian"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" @click.prevent="modifyLineWidth(.5)"
                                title="粗">
                                <i class="iconfont gls-zhong-zhixian"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" @click.prevent="modifyLineWidth(1)"
                                title="特粗">
                                <i class="iconfont gls-cu-zhixian"></i>
                            </a-button>
                            <a-divider type="vertical"></a-divider>
                            <a-slider :step=".1" :min=".1" :max="2" v-model:value="props.lineWidth" style="width: 100px;"
                                @change="(e: any) => modifyLineWidth(e)" />
                        </a-row>
                    </li>
                    <li>
                        <div class="title">边框样式</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button style="background-color: hsl(240 25% 96%)"
                                @click.prevent="() => { modifyBorderStyle([]) }" title="实线">
                                <i class="iconfont gls-xi-zhixian"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)"
                                @click.prevent="() => { modifyBorderStyle([.5, 1.2]) }" title="虚线">
                                <i class="iconfont gls-xuxian"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)"
                                @click.prevent="() => { modifyBorderStyle([.5, 2]) }" title="特虚">
                                <i class="iconfont gls-xuxian1"></i>
                            </a-button>
                            <a-divider type="vertical"></a-divider>
                            <a-slider :step=".2" :min=".1" :max="1" v-model:value="props.lineWidth" style="width: 100px;"
                                @change="(e: any) => modifyBorderStyle([.5, e])" />
                        </a-row>
                    </li>
                    <li>
                        <div class="title">圆角大小</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button style="background-color: hsl(240 25% 96%)" @click.prevent="modifyRadius(0)"
                                title="直角">
                                <i class="iconfont gls-zhijiao"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" @click.prevent="modifyRadius(5)"
                                title="圆角">
                                <i class="iconfont gls-yuanjiao"></i>
                            </a-button>
                            <a-divider type="vertical"></a-divider>
                            <a-slider v-model:value="props.radius" :step="1" :min="0" :max="10" style="width: 100px;"
                                @change="(e: any) => modifyRadius(e)" />
                        </a-row>
                    </li>
                    <li>
                        <div class="title">透明度</div>
                        <a-slider v-model:value="props.opacity" :step=".1" :min=".1" :max="2"
                            @change="(e: any) => modifyOpacity(e)" />
                    </li>
                    <li>
                        <div class="title">图层</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button style="background-color: hsl(240 25% 96%)" title="置于顶层"
                                @click.prevent="gls?.toMaxIndex(gls.getFocusNode() as Feature); message.info('置于顶层')">
                                <i class="iconfont gls-zhiyudingceng"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="上移一层"
                                @click.prevent="gls?.toUpIndex(gls.getFocusNode() as Feature);; message.info('上移一层')">
                                <i class="iconfont gls-shangyiyiceng"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="下移一层"
                                @click.prevent="gls?.toDownIndex(gls.getFocusNode() as Feature);; message.info('下移一层')">
                                <i class="iconfont gls-xiayiyiceng"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="置于底层"
                                @click.prevent="gls?.toMinIndex(gls.getFocusNode() as Feature); message.info('置于底层')">
                                <i class="iconfont gls-zhiyudiceng"></i>
                            </a-button>
                        </a-row>
                    </li>
                    <li>
                        <div class="title">对齐(针对Group,SelectArea)</div>
                        <a-row type="flex" align="middle" class="func-wrap" style="margin-bottom: 8px">
                            <a-button style="background-color: hsl(240 25% 96%)" title="左对齐" @click.prevent="toLeftAlign">
                                <i class="iconfont gls-zuoduiqi"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="垂直对齐"
                                @click.prevent="toVerticalAlign">
                                <i class="iconfont gls-chuizhijuzhongduiqi"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="右对齐" @click.prevent="toRightAlign">
                                <i class="iconfont gls-youduiqi"></i>
                            </a-button>
                        </a-row>
                        <a-row type="flex" align="middle" class="func-wrap" style="margin-bottom: 8px">
                            <a-button style="background-color: hsl(240 25% 96%)" title="顶对齐" @click.prevent="toTopAlign">
                                <i class="iconfont gls-dingduiqi"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="水平对齐"
                                @click.prevent="toHorizonalAlign">
                                <i class="iconfont gls-shuipingjuzhongduiqi"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="底对齐" @click.prevent="toBottomAlign">
                                <i class="iconfont gls-diduiqi"></i>
                            </a-button>
                        </a-row>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button style="background-color: hsl(240 25% 96%)" title="水平-弹性布局"
                                @click.prevent="toSpacebetween(AlignType.HORIZONAL)">
                                <i class="iconfont gls-chuizhi-flex"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="垂直-弹性布局"
                                @click.prevent="toSpacebetween(AlignType.VERTICAL)">
                                <i class="iconfont gls-shuiping-flex"></i>
                            </a-button>
                        </a-row>
                    </li>
                    <li>
                        <div class="title">操作</div>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button style="background-color: hsl(240 25% 96%)" title="复制"
                                @click.prevent="gls?.focusNode && gls?.recordFeature(gls.focusNode as Feature); message.info('复制了')">
                                <i class="iconfont gls-fuzhi"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="同步缩放"
                                @click.prevent="setTranformChild">
                                <i class="iconfont gls-scale-same"></i>
                            </a-button>
                        </a-row>
                        <a-row type="flex" align="middle" class="func-wrap">
                            <a-button style="background-color: hsl(240 25% 96%)" title="复制为图片到剪贴板"
                                @click.prevent="copyImageToClipboard()">
                                <i class="iconfont gls-fuzhitupian"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="复制为SVG到剪贴板"
                                @click.prevent="copySvgToClipboard()">
                                <i class="iconfont gls-SVG"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="水平翻转"
                                @click.prevent="revert(AlignType.HORIZONAL)">
                                <i class="iconfont gls-zuoyoufanzhuan"></i>
                            </a-button>
                            <a-button style="background-color: hsl(240 25% 96%)" title="垂直翻转"
                                @click.prevent="revert(AlignType.VERTICAL)">
                                <i class="iconfont gls-shangxiafanzhuan"></i>
                            </a-button>
                        </a-row>
                    </li>
                </ul>
            </div>
        </div>
        <canvas id="myCanvas" width="700" height="420" ref="cvs"></canvas>
        <a-modal v-model:open="isShowSaveImage" title="保存为图片" width="80vw">
            <a-row type="flex" justify="center">
                <a-spin v-if="exportImgLoading" />
                <img alt="" id="preview-img" width="80%" v-show="!exportImgLoading">
            </a-row>
            <template #footer>
                <a-button key="submit" type="primary" @click.prevent="onShowPreview()">切换模式</a-button>
                <a-button key="submit" type="primary" @click.prevent="onSaveImg()">下载图片</a-button>
                <a-button key="back" @click.prevent="isShowSaveImage = false">关 闭</a-button>
            </template>
        </a-modal>
        <a-modal v-model:open="isShowHelp" title="帮助" width="90vw" style="max-width: 1000px">
            <div class="list-of-instructions">
                <h4 class="title">基本操作: </h4>
                <ul>
                    <li>1.鼠标左键点击用于选择元素, 右键移动可以拖动画布, 滚轮缩放画布大小</li>
                    <li>2.创建矩形,圆形, 文本, 图片, 鼠标左键点击创建</li>
                    <li>3.创建折线, 鼠标左键点击创建, 右键点击结束绘制</li>
                    <li>4.创建自由画笔, 鼠标左键移动绘制, 松开后还会继续绘制, 右键点击结束绘制</li>
                </ul>
                <br />
                <div style="width: 50%" class="list-wrap">
                    <h4 class="title">快捷键列表: </h4>
                    <a-row type="flex" justify="space-between" class="row">
                        <span>删除元素</span> <a-tag>Del</a-tag>
                    </a-row>
                    <a-row type="flex" justify="space-between" class="row">
                        <span>撤销</span>
                        <div><a-tag>Ctrl</a-tag><a-tag>Z</a-tag></div>
                    </a-row>
                    <a-row type="flex" justify="space-between" class="row">
                        <span>恢复</span>
                        <div><a-tag>Ctrl</a-tag><a-tag>Y</a-tag></div>
                    </a-row>
                    <a-row type="flex" justify="space-between" class="row">
                        <span>合并为组(使用区域选择框选多个元素)</span>
                        <div><a-tag>Ctrl</a-tag><a-tag>U</a-tag></div>
                    </a-row>
                    <a-row type="flex" justify="space-between" class="row">
                        <span>去选区域选中的内容</span>
                        <div><a-tag>esc</a-tag></div>
                    </a-row>
                    <a-row type="flex" justify="space-between" class="row">
                        <span>双击空白处新建文本元素编辑, 双击文本元素可以编辑</span>
                        <div><a-tag>DBLCLICK</a-tag></div>
                    </a-row>
                </div>
            </div>
            <template #footer>
                <a-button key="back" @click.prevent="isShowHelp = false">关 闭</a-button>
            </template>
        </a-modal>
        <div class="update-time">
            <a-row type="flex" align="middle">
                <!-- <span style="margin-right: 10px;">最后更新时间: {{ env.BUILD_TIME }}</span> -->
                <a-button style="width: 34px;height: 34px;padding: 0;line-height: 34px;"
                    @click.prevent="isShowHelp = true"><i class="iconfont gls-bangzhu"
                        style="font-size: 20px"></i></a-button>
            </a-row>
        </div>
        <a-row class="stack-wrap">
            <a-row style="border-radius: 7px;overflow: hidden;margin-right: 10px;">
                <button @click.prevent="gls?.zoomTo(gls.scale - 1)"><i class="iconfont gls-jianhao"></i></button>
                <button style="border-radius: 0;width: 55px">缩放</button>
                <button @click.prevent="gls?.zoomTo(gls.scale + 1)"><i class="iconfont gls-jiahao"></i></button>
            </a-row>
            <a-row style="border-radius: 7px;overflow: hidden;">
                <button @click.prevent="stack?.undo()"><i class="iconfont gls-chexiao" /></button>
                <button @click.prevent="stack?.restore()"><i class="iconfont gls-huifu" /></button>
            </a-row>
        </a-row>
    </div>
    <router-view />

</template>

<script lang="ts" setup>
import { AlignType, CtrlType, Events, LinkStyle, FontFamily } from "@/Constants";
import Circle from "@/features/basic-shape/Circle";
import Img from "@/features/basic-shape/Img";
import Line from "@/features/basic-shape/Line";
import Rect from "@/features/basic-shape/Rect";
import Text from "@/features/basic-shape/Text";
import Link from "@/features/basic-shape/link/Link";
import Feature from "@/features/Feature";
import SelectArea from "@/features/function-shape/SelectArea";
import Group from "@/features/function-shape/Group";
import GridLine from "@/GridLine";
import { message } from "ant-design-vue";
import { onMounted, ref } from "vue";
import { GridStyle } from "../Constants";
import GridSystem from "../GridSystem";
import Stack from "../Stack";
import { IPoint } from "../Interface"
import { Utils } from "../utils"
import Pnt from "@/features/function-shape/Pnt";
import AdsorbPnt from "@/features/function-shape/func-pnts/AdsorbPnt";
import ScaleRuler from "@/ScaleRule";
import MiniMap from "@/MiniMap";
import Arrow from "@/features/function-shape/ctrl-pnts/Arrow";

const cvs = ref(null);
const activeI = ref(-1);
const isShowSide = ref(false);
const exportImgLoading = ref(true);
const exportImgMode = ref(true);
const props = ref<Partial<Feature & Rect & Line>>({
    opacity: 1,
    lineWidth: .2,
    radius: 0,
    fillStyle: ''
});
let gls = ref<GridSystem | null>(null);
let gl = ref<GridLine | null>(null);
let sr = ref<ScaleRuler | null>(null);
let minimap = ref<MiniMap | null>(null);
let stack = ref<Stack | null>(null);
let isShowMp = ref<boolean>(false);
let isShowSr = ref<boolean>(false);
let isShowGl = ref<boolean>(false);
const isShowSaveImage = ref(false);
const isShowHelp = ref(false);
const globalStrokeColor = ref("")
const globalBorderStyle = ref([])
const callback = ref<((remove?: boolean) => void) | undefined>(undefined);

onMounted(() => {
    reset();
})

function onSelectTool(index = 0, param?: any) {
    const gridSystem = gls.value;
    if (gridSystem) {
        document.removeEventListener("mousedown", mousedown)
        if (activeI.value === index) {
            activeI.value = -1
        }
        if (callback.value) { callback.value(); callback.value = undefined };
        switch (index) {
            case 0: // 选择区域
                message.info("按住左键移动吧!")
                gridSystem.enableSelectArea() as SelectArea;
                break;
            case 1: // 单击创建Rect
                message.info("点击画布创建吧!")
                let rect = new Rect(0, 0, 50, 20);
                rect.name = '你好'
                callback.value = gridSystem.singleClick2Rect(rect)
                break;
            case 2: // 单击创建Circle
                message.info("点击画布创建吧!")
                let circle = new Circle(0, 0, 50, 50);
                callback.value = gridSystem.singleClick2Rect(circle)
                break;
            case 3: // 点击创建Line
                message.info("点击画布创建吧!")
                let line = new Line();
                line.lineDashArr = globalBorderStyle.value;
                line.isClosePath = !!param;
                const div = document.createElement("div");
                div.innerText = "测试文本...";
                div.style.position = "fixed";
                div.style.pointerEvents = "none";
                div.style.border = "1px solid";
                div.style.background = "#fff";
                div.style.padding = "2px 5px";
                callback.value = gridSystem.continuousClick2Line(line, () => {
                    if (!!param) {
                        // let div: HTMLDivElement | null = null;
                        line.ctrlTypes = [CtrlType.PNT_CTRL]
                        line.hoverStyle = line.focusStyle = line.fillStyle = "rgba(138, 178, 249, .5)"
                        line.on(Events.MOUSE_ENTER, () => {
                            document.body.appendChild(div);
                        })
                        line.on(Events.MOUSE_MOVE, (e: any) => {
                            if (div) {
                                div.style.left = e.detail.x + 20 + "px";
                                div.style.top = e.detail.y + 20 + "px";
                            }
                        })
                        line.on(Events.MOUSE_LEAVE, () => {
                            document.body.removeChild(div)
                        })
                    }
                })
                break;
            case 4: // 自由笔
                message.info("点击移动绘制吧!")
                if (callback.value) { callback.value(); callback.value = undefined; return };
                function downMove2Line() {
                    let pen = new Line();
                    // pen.isPixelLen = true;
                    callback.value = gridSystem?.downMove2Line(pen, () => {
                    })
                }
                downMove2Line();
                break;
            case 5: // 创建文字
                var txt = prompt("请输入文字", "测试文字");
                if (txt) {
                    message.info("点击画布创建吧!")
                    let text = new Text(txt as string, 0, 0);
                    text.fitSize = true;
                    gridSystem.singleClick2Rect(text)
                }

                break;
            case 6: // 上传图片
                const input = document.createElement('input');
                input.type = "file";
                input.accept = "image/*";
                input.click();
                input.onchange = () => {
                    if (input.files && input.files.length > 0) {
                        const file = input.files[0] as File;
                        const reader = new FileReader();
                        reader.readAsDataURL(file);
                        reader.onload = function () {
                            message.info("点击画布创建吧!")
                            let img = new Img(reader.result as string, 0, 0);
                            gridSystem.singleClick2Rect(img)
                        }
                    }
                }
                break;
            case 7: // 是否显示网格
                if (!isShowGl.value) {
                    gl.value = new GridLine(gridSystem as GridSystem);
                    gl.value.draw();
                    gl.value.gridStyle = GridStyle.RANGE
                    gridSystem.cbAdsorption = true;
                    message.info("显示网格!");
                } else {
                    gl.value?.destroy();
                    gl.value = null;
                    gridSystem.cbAdsorption = false;
                    message.info("关闭网格!")
                }
                isShowGl.value = !isShowGl.value;
                break;
            case 8: // 是否吸附
                message.info("点击移动绘制吧!")
                const gpos1 = { x: 1, y: 1 }
                const rpos1 = gridSystem.getRelativePosByGridPos(gpos1);
                const unitSize = Utils.getUnitSize();
                const rect2 = new Rect(rpos1.x, rpos1.y, unitSize, unitSize)
                gridSystem.addFeature(rect2);
                rect2.cbCapture = false;
                const pathArr: IPoint[] = []
                gridSystem.on(Events.MOUSE_DOWN, () => {
                    gridSystem.cbDragBackground = false;
                    function mouseMove({ detail }) {
                        if (gridSystem) {
                            const pos = Utils.getMousePos(gridSystem?.domElement as Element, detail);
                            const rpos = gridSystem?.getRelativePos(pos);
                            const gpos = gridSystem?.getGridPosByRelativePos(rpos);
                            if (!pathArr.find(pa => pa.x == gpos.x && pa.y == gpos.y)) pathArr.push(gpos);
                        }
                    }
                    gridSystem.on(Events.MOUSE_MOVE, mouseMove)
                    gridSystem.on(Events.MOUSE_UP, () => {
                        gridSystem.off(Events.MOUSE_MOVE, mouseMove)
                        let index = 0;
                        if (pathArr[index].x == gpos1.x && pathArr[index].y == gpos1.y) {
                            var timer = setInterval(() => {
                                index++
                                const rpos2 = gridSystem.getRelativePosByGridPos(pathArr[index]);
                                rect2.setPos(rpos2.x, rpos2.y)
                                if (index > pathArr.length) {
                                    clearInterval(timer);
                                }
                            }, 1000)
                        }

                    })
                })
                // gridSystem.cbAdsorption = !gridSystem.cbAdsorption;
                break;
            case 10: // 内容适应宽高
                gridSystem.toFitView();
                break;
            case 11: // 内容适应宽高
                document.addEventListener("mousedown", mousedown)
                break;
            case 12: // 内容适应宽高
                message.info("点击画布创建吧!")
                let line2 = new Line();
                line2.lineDashArr = globalBorderStyle.value;
                line2.strokeStyle = "#483D8B"
                new Arrow(line2);
                if (callback.value) { callback.value(); callback.value = undefined; return };
                callback.value = gridSystem.continuousClick2CurveLine(line2)
                break;
            case 13: // 内容适应宽高
                if (callback.value) { callback.value(true); callback.value = undefined; return };
                message.info("取消画笔!")
                break;
            case 14: // 小地图
                if (!isShowMp.value) {
                    minimap.value = new MiniMap(gridSystem as GridSystem);
                    gridSystem.on(Events.DRAW, () => {
                        minimap.value?.draw()
                    })
                    message.info("打开小地图!")
                } else {
                    minimap.value?.destroy();
                    minimap.value = null;
                    message.info("关闭小地图!")
                }
                isShowMp.value = !isShowMp.value;
                break;
            case 15: // 标尺
                if (!isShowSr.value) {
                    sr.value = new ScaleRuler(gridSystem as GridSystem);
                    sr.value.draw()
                    message.info("打开标尺!")
                } else {
                    sr.value?.destroy();
                    sr.value = null;
                    message.info("关闭标尺!")
                }
                isShowSr.value = !isShowSr.value;
                break;
            default:
                break;
        }
        if (activeI.value < 0) {
            return
        }
        activeI.value = index;
    } else {
        message.info("gridSystem不存在!")
    }
}

function reset(clear = false) {
    if (clear) localStorage.setItem("features", '');
    if (gls.value) {
        gls.value.destroy();
        gls.value = null;
    }
    let canvasDom = cvs.value as unknown as HTMLCanvasElement;
    const gridSys = new GridSystem(canvasDom);
    gridSys.initEventListener();
    gridSys.loadFont(FontFamily.SHISHANG);
    gridSys.draw(true)
    gls.value = gridSys;
    setSize(canvasDom);
    onSelectTool(7)
    stack.value = new Stack(gridSys);

    gls.value.on(Events.CHANGED, () => stack.value?.record())

    const rect = new Rect(50, 30, 50, 50);
    gls.value.addFeature(rect)

    const rect1 = new Rect(20, 20, 10, 10);
    rect.addChild(rect1)

    const circle = new Circle(290, 80, 50);
    gls.value.addFeature(circle)

    const link = new Link(rect, circle);
    const generatePnts = link.getGeneratePointArr(LinkStyle.CURVE3_HORIZINAL)
    gls.value.addFeature(link)
    // const linkPnts = Utils.getInterpolatePnts(link.pointArr);
    link.pointArr = generatePnts

    gls.value.addFeature(new Group(circle, rect, link))

    const text2 = new Text(`Rect, Img, Video, Text
Circle, Line, Pen, Link
(矩形,图片,文本,线段,连接线等..)`, 180, 300)
    gls.value.addFeature(text2)
    const line = new Line([
        { x: 100, y: 100 },
        { x: 200, y: 200 },
    ])
    gls.value.addFeature(line)
    line.setBezierPnts([
        { x: 150, y: 200 },
    ])
}

function mousedown() {
    const glss = gls.value as GridSystem;
    glss.cbOperable = false;
    let width = Utils.getUnitSize();
    const adsorbPnt = new AdsorbPnt(8, false);
    var mousemove = () => {
        let gpos = glss.getGridPosByRelativePos(adsorbPnt.position);
        let nrpos = glss.getRelativePosByGridPos(gpos)
        let rect = new Pnt(nrpos.x, nrpos.y, width, width);
        console.log(nrpos);
        rect.fillStyle = rect.hoverStyle = props.value.fillStyle || "#000";
        rect.strokeStyle = "transparent"
        rect.cbSelect = false;
        if (!glss.features.find(f => f.position.x === nrpos.x && f.position.y === nrpos.y)) {
            glss.addFeature(rect);
            glss.focusNode = null;
        }
    }
    var mouseup = () => {
        glss.cbOperable = true;
        glss.removeFeature(adsorbPnt);
        document.removeEventListener("mousemove", mousemove)
        document.removeEventListener("mouseup", mouseup)
    }
    document.addEventListener("mousemove", mousemove)
    document.addEventListener("mouseup", mouseup)
}


const previewBase64 = ref('')
function onSaveImg() {
    if (previewBase64.value) {
        Utils.downloadFile([Utils.base64ToBlob(previewBase64.value)], { type: "image/png" })
    }
}

function onShowPreview() {
    isShowSaveImage.value = true;
    exportImgLoading.value = true;
    setTimeout(() => {
        if (gls.value) {
            var base64 = gls.value.toImage(exportImgMode.value);
            let img = document.getElementById("preview-img") as HTMLImageElement;
            img.src = base64;
            previewBase64.value = base64;
            exportImgLoading.value = false;
        }
        exportImgMode.value = !exportImgMode.value
    }, 1000);
}

function onSaveFile() {
    if (gls.value?.features && gls.value.features.length <= 0) {
        return message.warning("没有元素,保存啥?")
    }
    let str = gls.value?.save();
    const text = JSON.stringify(str)
    Utils.downloadFile([text], { type: "text/plain;charset=utf-8" })
}
function onImportFile() {
    Utils.selectFiles().then(res => {
        const reader = new FileReader();
        reader.readAsText(res[0]);
        reader.onload = function () {
            gls.value?.loadData(reader.result as string);
        }
    })
}

function linkTo(url: string) {
    window.open(url);
}

function setSize(canvasDom: HTMLCanvasElement) {
    canvasDom.width = document.documentElement.clientWidth - 4;
    canvasDom.height = document.documentElement.clientHeight - 4;

    window.onresize = () => {
        canvasDom.width = document.documentElement.clientWidth - 4;
        canvasDom.height = document.documentElement.clientHeight - 4;
    }
}

function toTopAlign() {
    let sa = gls.value?.getFocusNode();
    sa && sa.toTopAlign();
    message.info('顶对齐');
}
function toBottomAlign() {
    let sa = gls.value?.getFocusNode();
    sa && sa.toBottomAlign();
    message.info('底对齐');
}
function toRightAlign() {
    let sa = gls.value?.getFocusNode();
    sa && sa.toRightAlign();
    message.info('右对齐');
}
function toLeftAlign() {
    let sa = gls.value?.getFocusNode();
    sa && sa.toLeftAlign();
    message.info('左对齐');
}
function toHorizonalAlign() {
    let sa = gls.value?.getFocusNode();
    sa && sa.toHorizonalAlign();
    message.info('水平对齐');
}
function toVerticalAlign() {
    let sa = gls.value?.getFocusNode();
    sa && sa.toVerticalAlign();
    message.info('垂直对齐');
}
function toSpacebetween(flexFLow = AlignType.HORIZONAL) {
    let sa = gls.value?.getFocusNode();
    // sa && sa.toSpaceAroud();
    sa && sa.toSpaceBetween(sa.getBasicChilds(), flexFLow);
    message.info('均匀分布');
}


function modifyStrokeStyle(color: string) {
    globalStrokeColor.value = color;
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode) {
        focuseNode.strokeStyle = color;
    }
}

function modifyFillStyle(color: string) {
    let focuseNode = gls.value?.getFocusNode();
    props.value.fillStyle = color;
    if (focuseNode) {
        focuseNode.fillStyle = focuseNode.hoverStyle = focuseNode.focusStyle = color;
    }
}

function modifyBorderStyle(arr: number[]) {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode) {
        focuseNode.lineDashArr = arr;
    }
}

function modifyLineWidth(width: number) {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode) {
        focuseNode.lineWidth = width;
    }
}

function modifyRadius(radius: number) {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode && focuseNode instanceof Rect) {
        focuseNode.radius = radius;
    }
}

function modifyOpacity(opacity: number) {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode) {
        focuseNode.opacity = opacity;
    }
}

function setTranformChild() {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode) {
        focuseNode.cbTransformChild = !focuseNode.cbTransformChild;
        console.log(focuseNode.cbTransformChild, "focuseNode.cbTransformChild");
    }
    message.info('同步缩放');
}

function copyImageToClipboard() {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode && gls.value) {
        gls.value.copyImageToClipboard(focuseNode).then(blob => {
            let reader = new FileReader();
            reader.readAsDataURL(blob);
            reader.onload = (res) => {
                window.open('', '_blank')?.document.write(`<html><body><img src='${res.target?.result}'></body></html>`);
            }
        })
    }
    message.info('已复制为图片到剪贴板');
}

function copySvgToClipboard() {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode && gls.value) {
        gls.value.copySvgToClipboard(focuseNode).then(res => {
            console.log(res, "res");
            window.open('', '_blank')?.document.write(res);
        })
    }
    message.info('已复制为SVG到剪贴板');
}

function revert(direction: AlignType) {
    let focuseNode = gls.value?.getFocusNode();
    if (focuseNode && gls.value) {
        focuseNode.revert(direction)
    }
    message.info('镜像翻转');
}
</script>

<style scoped lang="less">
.app-container {
    position: relative;
    font-family: "glsfont";
    overflow: hidden;

    .top-toolbar {
        position: absolute;
        left: 50%;
        top: 20px;
        padding: 0 10px;
        transform: translateX(-50%);
        background: #fff;
        box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, .17), 0px 0px 3px 0px rgba(0, 0, 0, .08), 0px 7px 14px 0px rgba(0, 0, 0, .05);
        border-radius: 8px;
        color: #676767;
        min-width: 250px;
    }

    .list-wrap {
        font-size: 14px;
        position: relative;
        z-index: 100;

        li {
            padding: 8px 15px;
            border-radius: 5px;
            color: #333;
            margin: 5px 0;
            cursor: pointer;

            &:hover {
                background-color: rgba(222, 230, 237, .5);
            }

            &>i {
                margin-right: 4px;
            }
        }
    }

    .props-tab {
        position: absolute;
        left: 20px;
        top: 20px;

        .props-page {
            margin-top: 10px;
            border-radius: 10px;
            padding: 5px;
            float: left;
            // width: 180px;
            background-color: rgba(250, 250, 250, .95);
            box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, .17), 0px 0px 3px 0px rgba(0, 0, 0, .08), 0px 7px 14px 0px rgba(0, 0, 0, .05);

            .list-wrap {
                font-size: 14px;
                position: relative;
                z-index: 100;

                li {
                    padding: 8px 15px;
                    border-radius: 5px;
                    color: #333;
                    margin: 5px 0;
                    cursor: pointer;

                    &:hover {
                        background-color: rgba(222, 230, 237, .5);
                    }

                    &>i {
                        margin-right: 4px;
                    }
                }

                li.canvas-bg {
                    button {
                        width: 20px;
                        height: 20px;
                        margin-right: 5px;

                    }

                    .color-picker {
                        width: 20px;
                        height: 20px;
                        padding: 0px;
                    }
                }
            }
        }

        .title {
            font-size: 12px;
            margin-bottom: 6px;
        }

        .props-setting {
            // margin-left: 15px;


            .list-wrap {
                li {
                    padding: 4px 10px;

                    &:hover {
                        background-color: transparent;
                    }
                }
            }

            .func-wrap {
                display: flex;
                margin-top: 8px;

                button {
                    margin-right: 12px;
                    width: 32px;
                    height: 32px;
                    padding: 0;

                    i {
                        font-size: 20px;
                    }
                }

                .color-picker {
                    display: inline-block;
                    width: 32px;
                    height: 32px;
                    border: 1px solid #d9d9d9;
                    border-radius: 5px;
                    margin-left: 5px;
                    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02);
                }
            }
        }
    }

    .icon-wrap {
        width: 25px;
        height: 25px;
        padding: 5px;
        margin: 5px 10px;
        margin-left: 0;
        cursor: pointer;
        text-align: center;
        line-height: 25px;
        border-radius: 5px;

        &.subscript {
            position: relative;
            counter-increment: chapter;

            &:after {
                content: ". " counter(chapter);
                /* 使用counters函数获取当前计数值并显示 */
                /* 递增计数器 */
                position: absolute;
                right: 0px;
                bottom: -2px;
                font-size: 12px;
                font-weight: lighter;
                color: #000;
            }
        }

        i {
            font-size: 22px;
        }

        &:hover {
            background-color: #C6E2F8;
        }

        &.active {
            background-color: rgba(174, 214, 241, .9);
        }

        &.gengduo {
            position: relative;
            z-index: 100;
            border-radius: 6px;
            background-color: rgba(192, 202, 210, .5);
            box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, .17), 0px 0px 3px 0px rgba(0, 0, 0, .08), 0px 7px 14px 0px rgba(0, 0, 0, .05);

            &:hover {
                background-color: rgba(192, 202, 210, 1);
            }
        }

        &:hover {
            &>.hover-tab {
                padding: 4px 7px;
                width: 80px;
                display: inline-block;
            }

            li:hover {
                background-color: rgba(192, 202, 210, .5);
            }
        }

        .hover-tab {
            width: 200px;
            background-color: #fff;
            border-radius: 5px;
            font-size: 14px;
            // border: 1px solid #d9d9d9;
            box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, .17), 0px 0px 3px 0px rgba(0, 0, 0, .08), 0px 7px 14px 0px rgba(0, 0, 0, .05);
            display: none;
            margin-top: 20px;
            padding: 10px;
            text-align: left;
            line-height: 14px;

            li {
                padding: 5px;
            }
        }
    }

    .right-click-panel {
        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;
    }

    .update-time {
        position: fixed;
        right: 5px;
        bottom: 5px;
        color: #999;
        font-size: 12px;
        // background-color: #fff;
        padding: 5px 10px;
        border-radius: 5px;
    }

    .stack-wrap {
        position: fixed;
        left: 10px;
        bottom: 10px;
        color: #999;
        font-size: 12px;

        i {
            font-size: 23px;
        }

        button {
            line-height: 34px;
            padding: 0 0px;
            width: 45px;
            height: 34px;
            border: none;
            background-color: #ececf4;
            border-radius: 0;

            &:hover {
                background-color: rgb(224, 224, 243);
            }
        }
    }
}

.list-of-instructions {
    .list-wrap {
        .row {
            border-bottom: 1px solid rgba(240, 240, 240, 1);
            padding: 5px;
            margin: 5px 0;
        }
    }

}
</style>